// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module conv_422_to_444 
#(parameter
    FIFO_DEPTH = 0
)
(
    input  wire I_sclk,
    input  wire I_rst_n,
    //
    input  wire I_new_frame,
    //
    input  wire I_in_fifo_empty,
    output reg  O_in_fifo_rdreq,
    input  wire [ 31: 0] I_in_fifo_rddata,
    //
    input  wire [ 15: 0] I_out_fifo_usedw,
    output wire          O_out_fifo_wrreq,
    output wire [ 23: 0] O_out_fifo_wdata
);

/******************************************************************************
                                <localparams>
******************************************************************************/
localparam
    OUT_FIFO_TH = 16;

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  in_fifo_data_valid;
reg  in_fifo_data_valid_dly;
reg  out_fifo_wrreq;
reg  [ 23: 0] out_fifo_wdata;

/******************************************************************************
                                <module body>
******************************************************************************/
always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_in_fifo_rdreq <= 1'b0;
    else if (O_in_fifo_rdreq)
        O_in_fifo_rdreq <= 1'b0;
    else if (!I_in_fifo_empty && I_out_fifo_usedw < FIFO_DEPTH - 16)
        O_in_fifo_rdreq <= 1'b1;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        in_fifo_data_valid <= 1'b0;
    else if (I_new_frame)
        in_fifo_data_valid <= 1'b0;
    else
        in_fifo_data_valid <= O_in_fifo_rdreq;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        in_fifo_data_valid_dly <= 1'b0;
    else if (I_new_frame)
        in_fifo_data_valid_dly <= 1'b0;
    else
        in_fifo_data_valid_dly <= in_fifo_data_valid;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        out_fifo_wrreq <= 1'b0;
    else if (I_new_frame)
        out_fifo_wrreq <= 1'b0;
    else
        out_fifo_wrreq <= in_fifo_data_valid | in_fifo_data_valid_dly;

always @(posedge I_sclk)
    if (in_fifo_data_valid)
        out_fifo_wdata <= {I_in_fifo_rddata[15:8],I_in_fifo_rddata[7:0],I_in_fifo_rddata[23:16]};
    else if (in_fifo_data_valid_dly)
        out_fifo_wdata <= {I_in_fifo_rddata[31:24],I_in_fifo_rddata[7:0],I_in_fifo_rddata[23:16]};

yuv2rgb u_yuv2rgb
(
    .I_pclk(I_sclk),
    .I_vsync(1'b0),
    .I_hsync(1'b0),
    .I_de(out_fifo_wrreq),
    .I_data(out_fifo_wdata),
    .O_vsync(),
    .O_hsync(),
    .O_de(O_out_fifo_wrreq),
    .O_data(O_out_fifo_wdata),
    .I_enable(1'b1)
);

endmodule
`default_nettype wire

